﻿using System.Collections.ObjectModel;
using System.Linq;
using Microsoft.TeamFoundation.WorkItemTracking.Client;
using WorkItem = VisualWip.Core.WorkItem;

namespace VisualWip.TFS2010Providers
{
    public class WorkItemHierarchicalQuery : WorkItemQueryBase
    {
        protected override Collection<WorkItem> RunGetWork(TfsWorkItemWorkProvider workItemWorkProvider)
        {
            var batch = new BatchReadParameterCollection();
            var query = new Query(workItemWorkProvider.WorkItemStore, QueryText, workItemWorkProvider.QueryContext);
            WorkItemLinkInfo[] links = query.RunLinkQuery();

            if (links.Length == 0)
                return new Collection<WorkItem>();

            return WorkItemTransformer.BuildHierarchi(links,
                                                      GetFlatListOfWorkItems(workItemWorkProvider, links, batch,
                                                                             CreateSelectWorkItemStatement(query)),DownloadDisplayFieldsOnly);
        }

        protected static string CreateSelectWorkItemStatement(Query query)
        {
            string fieldNames = string.Join(", ",
                                            from fieldDefinition in query.DisplayFieldList.OfType<FieldDefinition>()
                                            select fieldDefinition.ReferenceName);

            return string.Format("SELECT {0} FROM WorkItems", fieldNames);
        }

        protected override int RunGetWorkCount(TfsWorkItemWorkProvider workItemWorkProvider)
        {
            var query = new Query(workItemWorkProvider.WorkItemStore, QueryText, workItemWorkProvider.QueryContext);
            WorkItemLinkInfo[] links = query.RunLinkQuery();
            return links.Count(x => x.SourceId == 0);
        }

        private static WorkItemCollection GetFlatListOfWorkItems(TfsWorkItemWorkProvider workItemWorkProvider,
                                                                 WorkItemLinkInfo[] links,
                                                                 BatchReadParameterCollection batch,
                                                                 string selectStatement)
        {
            foreach (WorkItemLinkInfo workItemLinkInfo in links)
            {
                if (!batch.Contains(workItemLinkInfo.TargetId))
                {
                    batch.Add(new BatchReadParameter(workItemLinkInfo.TargetId));
                }
            }

            return workItemWorkProvider.WorkItemStore.Query(batch,
                                                            selectStatement);
        }
    }
}